feat(trust): gateway echo-on-deny (Phase 2) + trust-none default (Phase 3)#1273
feat(trust): gateway echo-on-deny (Phase 2) + trust-none default (Phase 3)#1273chaodu-agent wants to merge 2 commits into
Conversation
- Phase 2: on Decision::DenyIdentity, echo the sender their ID via adapter.send_message so they can request access (request-access UX). Throttled to 1 echo per (platform,sender) per 5min (LazyLock map) to prevent amplification. DenyScope stays silent (not a security boundary). - Phase 3 (gateway): flip GATEWAY_ALLOW_ALL_USERS default true→false, so gateway L3 is trust-none by default. L2 (channels) stays open. Admit via GATEWAY_ALLOWED_USERS or GATEWAY_ALLOW_ALL_USERS=true. Ships in pre-beta (self-use). emilie unaffected (own image + WS path, which doesn't use this registry/echo). Discord/Slack registry entries unchanged (still behavior-preserving allow-all). Refs #1264 #1269
|
LGTM ✅ — Phase 2 echo-on-deny and Phase 3 trust-none default are well-implemented, correctly scoped, and ship with appropriate safeguards. What This PR DoesImplements the gateway trust echo for denied identity requests (Phase 2) and flips the How It Works
Findings
What's Good (🟢)
Baseline Check
Note: Unbounded throttle map (non-blocking)The |
pahud
left a comment
There was a problem hiding this comment.
Review
Code correctness:
Decisionmatch inprocess_gateway_eventis exhaustive (Allow/DenyIdentity/DenyScopevia_) — matches the enum intrust.rs. Good use of_to also catch any future variant defensively.- Echo throttle (
ECHO_THROTTLE+echo_allowed) is a simple per-(platform, sender)5-min window backed by aMutex<HashMap>— correct and adequately tested (echo_allowed_throttles_repeat_within_window). Fine for pre-beta self-use scale; would want a TTL/eviction sweep if this ever sees real traffic (unbounded map growth), but not a blocker at current scope. DenyScopestaying silent (no echo) is correctly scoped per the L2/L3 trust model from the ADR.- The
GATEWAY_ALLOW_ALL_USERSdefault flip (true → false) is a single, well-isolated line change with a clear comment explaining the behavior change. send_messageerrors are intentionally swallowed (let _ = ...) on the echo path — reasonable, since a failed echo shouldn't fail event processing, though consider at least atracing::warn!on error for observability.
Scope/safety:
- Correctly scoped to pre-beta only per the PR description (emilie unaffected).
- Discord/Slack registries unchanged — consistent with the stated deviation from strict phase ordering.
Gap found: docs/config-reference.md still documents GATEWAY_ALLOW_ALL_USERS default as true. This PR changes the code default to false but doesn't update that doc table — it'll be actively wrong once merged. Not a blocker, but should be fixed in this PR or immediately after.
CI: all checks green (33/33 smoke tests, clippy, unit tests).
Approving — please push a doc fix for the GATEWAY_ALLOW_ALL_USERS default in docs/config-reference.md before or right after merge.
thepagent
left a comment
There was a problem hiding this comment.
Approved as code owner. See detailed review from @pahud above — code is correct (exhaustive Decision match, tested throttle, well-scoped default flip). One follow-up needed: docs/config-reference.md still lists GATEWAY_ALLOW_ALL_USERS default as true; should be updated to false to match this change.
Enables trust-none for the gateway path (Telegram/LINE/…) with the request-access echo, so you can see the deny + echo UX end-to-end. Scoped intent: only pre-beta (self-use) runs this; emilie is unaffected (its own image + WS path, which doesn't use this registry/echo).
Changes
DenyIdentity, reply to the sender with their ID + how to request access (adapter.send_message). Throttled to 1 echo per (platform, sender) / 5 min (LazyLock map) to prevent amplification.DenyScopestays silent (scope isn't a security boundary).GATEWAY_ALLOW_ALL_USERSdefaulttrue → false. Gateway L3 is now deny-all unlessGATEWAY_ALLOWED_USERSlists the sender (orGATEWAY_ALLOW_ALL_USERS=true). L2 (channels) stays open.Gateway deployments on this image now deny unknown users by default. To keep a bot working:
GATEWAY_ALLOWED_USERS=<uid,…>, orGATEWAY_ALLOW_ALL_USERS=true(old behavior).Discord/Slack registry entries are unchanged (still behavior-preserving allow-all). Deviates from the strict #1269 phase order (deny-flip before privatization) — accepted because it ships only to pre-beta (self-use) for validation.
How to test (Telegram)
GATEWAY_ALLOWED_USERS=<your uid>→ you're admitted.⚠️ You are not on this bot's trusted list. Your ID: <id> …(once per 5 min).Testing
--features unified -D warningsclean; 10/10 gateway tests (incl. newecho_allowed_throttles_repeat_within_window).Refs #1264 #1269